x86/PoD: defer nested P2M flushes
authorJan Beulich <jbeulich@suse.com>
Wed, 20 Oct 2021 10:42:44 +0000 (12:42 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 20 Oct 2021 10:42:44 +0000 (12:42 +0200)
commit6d187caae50284625af8799a79712c7a4c6a9a59
tree643a31bc4537975d6464d2b20c8d0cc9e273ac41
parent6809998c5f8f1d2e26ac9e867af8ac71e7a66cf2
x86/PoD: defer nested P2M flushes

With NPT or shadow in use, the p2m_set_entry() -> p2m_pt_set_entry() ->
write_p2m_entry() -> p2m_flush_nestedp2m() call sequence triggers a lock
order violation when the PoD lock is held around it. Hence such flushing
needs to be deferred. Steal the approach from p2m_change_type_range().
(Note that strictly speaking the change at the out_of_memory label is
not needed, as the domain gets crashed there anyway. The change is being
made nevertheless to avoid setting up a trap from someone meaning to
deal with that case better than by domain_crash().)

Similarly for EPT I think ept_set_entry() -> ept_sync_domain() ->
ept_sync_domain_prepare() -> p2m_flush_nestedp2m() is affected. Make its
p2m_flush_nestedp2m() invocation conditional. Note that this then also
alters behavior of p2m_change_type_range() on EPT, deferring the nested
flushes there as well. I think this should have been that way from the
introduction of the flag.

Reported-by: Elliott Mitchell <ehem+xen@m5p.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
xen/arch/x86/mm/p2m-ept.c
xen/arch/x86/mm/p2m-pod.c